import { useUserStore } from '@/stores'
import axios, { type Method } from 'axios'
import { showToast } from 'vant'
import router from '@/router'
const baseURL = 'https://consult-api.itheima.net'
const instance = axios.create({
  // 基地址
  baseURL,
  // 请求超时时间 毫秒
  timeout: 10000
})
// error 错误示范不能写在外面
// const userStore = useUserStore()
// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    // token请求头携带，
    // 每次发请求都要拿到最新的token 获取token的是写在请求拦截器里面的
    // useStore组件外使用 不能写在最外层 由于引入顺序的问题，这将失败 必须写在里面
    const userStore = useUserStore()
    const token = userStore.user?.token
    // console.log(111, token)
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    // 错误响应处理，响应是成功的但业务是失败的
    // 在医疗项目中 后端的code如果不是10000就代表业务失败
    // 1. 根据code字段判断业务失败 2. 做错误提示 3. 返回Promise的reject状态
    if (response.data.code !== 10000) {
      // 业务失败
      showToast(response.data.message || '业务失败')
      return Promise.reject(response.data)
    }
    // 数据剥离
    return response.data
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    /**
     * 401token失效处理
     * 1. 判断401
     * 2. 是401 清除token 本地持久化也要清（pinia插件自带持久化，所以只清除pinia）
     * 3. 跳转到登录页
     *    额外需求：
     *      假设用户当前访问的页面是playground?a=1&b=2
     *      token失效了 跳转到登录页了 登录后 跳回到之前的页面 playground?a=1&b=2(体验更好)
     */
    if (error.response.status === 401) {
      const userStore = useUserStore()
      userStore.delUser()
      // 获取当前页面的路径 fullPath完整的路径 path不是完整的路径 这里要用fullPath
      // console.log(router.currentRoute.value.fullPath)
      const returnUrl = router.currentRoute.value.fullPath
      router.push({
        path: '/login',
        query: {
          returnUrl
        }
      })
    }
    return Promise.reject(error)
  }
)

// 封装个request函数 - 通用的请求函数
// request<返回值类型>(url必填的, method可选默认是Get, submitData可选的)
type ApiResponse<T = any> = {
  code: number
  message: string
  data: T
}
const request = <T = any>(
  url: string,
  method: Method = 'GET',
  submitData?: object
) => {
  return instance.request<T, ApiResponse<T>>({
    url,
    method,
    // 首先大小写要处理好，toUpperCase记得要用大写的GET做全等
    // toLowerCase 要用小写get做全等
    // method.toUpperCase === 'GET' //error  toUpperCase函数 是要执行
    // method判断 是get 就是params字段 不是get就是data字段
    [method.toUpperCase() === 'GET' ? 'params' : 'data']: submitData
  })
}

export { instance, request, baseURL }
